package com.jnc.pay.util.secret;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.digest.MD5;
import com.jnc.pay.constant.SysConstant;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * @Auther: jjn
 * @Date: 2020/7/7 14:06
 * @Desc: 微信AES解密工具类
 */
public class WechatAESUtil {

    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "AES";
    /**
     * 加解密算法/工作模式/填充方式
     */
    private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS7Padding";

    private static BouncyCastleProvider bouncyCastleProvider = null;
    /**
     * 解密实例--防止内存泄漏(java.security.NoSuchProviderException: No such provider: BC异常)
     * @return
     * BouncyCastleProvider
     * @throws
     */
    public static synchronized BouncyCastleProvider getProviderInstance() {
        if (bouncyCastleProvider == null) {
            bouncyCastleProvider = new BouncyCastleProvider();
        }
        return bouncyCastleProvider;
    }

    /**
     * AES加密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) {
        try{
            // 创建密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
            SecretKeySpec spec =
                    new SecretKeySpec(MD5.create().digestHex(key, SysConstant.CHARSET_NAME).toLowerCase().getBytes(), ALGORITHM);
            // 初始化
            cipher.init(Cipher.ENCRYPT_MODE, spec);
            return Base64.encode(cipher.doFinal(data.getBytes()));
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES解密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key) {
        try{
            Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
            SecretKeySpec spec =
                    new SecretKeySpec(MD5.create().digestHex(key, SysConstant.CHARSET_NAME).toLowerCase().getBytes(), ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, spec);
            return new String(cipher.doFinal(Base64.decode(data)));
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

}
